package cn.itcast.wanxinp2p.account.service.impl;

import cn.itcast.wanxinp2p.account.common.AccountErrorCode;
import cn.itcast.wanxinp2p.account.mapper.AccountMapper;
import cn.itcast.wanxinp2p.account.model.Account;
import cn.itcast.wanxinp2p.account.model.AccountDTO;
import cn.itcast.wanxinp2p.account.model.AccountLoginDTO;
import cn.itcast.wanxinp2p.account.model.AccountRegisterDTO;
import cn.itcast.wanxinp2p.account.service.AccountService;
import cn.itcast.wanxinp2p.account.service.SmsService;
import cn.itcast.wanxinp2p.common.domain.BusinessException;
import cn.itcast.wanxinp2p.common.domain.RestResponse;
import cn.itcast.wanxinp2p.common.domain.StatusCode;
import cn.itcast.wanxinp2p.common.util.PasswordUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hmily.annotation.Hmily;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;

@Slf4j
@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements AccountService {
    @Resource
    SmsService smsService;
    @Resource
    RedisTemplate<String, String> redisTemplate;
    @Resource
    AccountMapper accountMapper;

    @Override
    public RestResponse getSMSCode(String mobile) {
        RestResponse res = smsService.getSMSCode(mobile);
        return res;

    }

    @Override
    public RestResponse<Integer> checkMobile(String mobile, String key, String code) {
        String redisKey = redisTemplate.opsForValue().get(key);

        if (Objects.equals(code, redisKey)) {
            LambdaQueryWrapper<Account> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Account::getMobile, mobile);
            return RestResponse.success(accountMapper.selectCount(wrapper) > 0 ? 1 : 0);//校验手机号是否存在
        }
        throw new BusinessException(AccountErrorCode.E_140152);//如果验证失败,抛异常
    }

    @Override
    @Hmily(confirmMethod = "confirmRegister",cancelMethod = "cancelRegister")
    public AccountDTO register(AccountRegisterDTO registerDTO) {
        Account account = new Account();
        account.setUsername(registerDTO.getUsername());
        account.setMobile(registerDTO.getMobile());
        account.setPassword(PasswordUtil.generate(registerDTO.getMobile()));
        account.setDomain("c");
        account.setStatus(StatusCode.STATUS_OUT.getCode());
        save(account);
        return convertAccountEntityToDTO(account);
    }
    public void confirmRegister(AccountRegisterDTO registerDTO) {
        log.info("execute confirmRegister");
    }

    public void cancelRegister(AccountRegisterDTO registerDTO) {
        log.info("execute cancelRegister");
        //删除账号
        remove(Wrappers.<Account>lambdaQuery().eq(Account::getUsername,
                registerDTO.getUsername()));
    }

    @Override
    public AccountDTO login(AccountLoginDTO accountLoginDTO) {
        Account account = null;
        if (accountLoginDTO.getDomain().equalsIgnoreCase("c")) {
            account = getAccountByMobile(accountLoginDTO.getMobile());//获取c端用户
        } else {
            account = getAccountByUsername(accountLoginDTO.getUsername());//获取b端

        }
        if (account == null) {
            throw new BusinessException(AccountErrorCode.E_130104); // 用户不存在
        }
        AccountDTO accountDTO = convertAccountEntityToDTO(account);
       //短信验证码登录，不做密码校验
            return accountDTO;
        } //验证密码


    /**
     *    根据手机获取账户信息
     *    @param mobile 手机号
     *    @return 账户实体
     */
    private Account getAccountByMobile(String mobile) {
        return getOne(new QueryWrapper<Account>().lambda()
                .eq(Account::getMobile, mobile));
    }

    /**
     *    根据用户名获取账户信息
     *    @param username 用户名
     *    @return 账户实体
     */
    private Account getAccountByUsername(String username) {
        return getOne(new QueryWrapper<Account>().lambda()
                .eq(Account::getUsername, username));
    }

    /**
     *    entity转为dto
     *    @param entity对象
     *    @return dto对象
     */
    private AccountDTO convertAccountEntityToDTO(Account entity) {
        if (entity == null) {
            return null;
        }
        AccountDTO dto = new AccountDTO();
        BeanUtils.copyProperties(entity, dto);
        return dto;
    }


}
